/**
 * 树结构工具包
 */

const loop=function(){}

//生成唯一标识
function guid(){
  function S4(){
    return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
  }
  return (S4()+S4()+'-'+S4()+'-'+S4()+'-'+S4()+'-'+S4()+S4()+S4());
}

//遍历树结构(回调return false结束遍历)
function foreachTree(tree,cb=loop,op={}){
  let option={
    children:'children',
  };
  option=Object.assign(option,op);
  function initChildren(item){
    if(cb(item)===false){
      return false;
    }
    if((item[option.children] instanceof Array)&&item[option.children].length===0){
      delete item[option.children];
    }
    if(!item[option.children]){
      return true;
    }

    for(let i=0;i<item[option.children].length;i++){
      if(initChildren(item[option.children][i])===false){
        return false;
      }
    }
  }

  for(let i=0;i<tree.length;i++){
    if(initChildren(tree[i])===false){
      break;
    }
  }
  return tree;
}

//格式化树
function formatTree(tree,cb=loop,op={}){
  let option={
    id:'_id',
    children:'children',
    parent:'_parent',
    level:'_level',
    pid:'_pid',
  };
  option=Object.assign(option,op);
  let level=0;
  function initChildren(item){
    item[option.level]= ++level;
    item[option.id]=guid();
    cb(item);
    if((item[option.children] instanceof Array)&&item[option.children].length===0){
      delete item[option.children];
    }
    if(!item[option.children]){
      return;
    }
    for(let i=0;i<item[option.children].length;i++){
      item[option.children][i][option.pid]=item[option.id];
      item[option.children][i][option.parent]=item;
      initChildren(item[option.children][i]);
      --level;
    }
  }

  for(let i=0;i<tree.length;i++){
    level=0;
    initChildren(tree[i])
  }
  return tree;
}

//根据id查找元素
function findById(tree,id,op={}){
  let option={
    id:'_id',
    children:'children',
  };
  option=Object.assign(option,op);
  let node=null;
  foreachTree(tree,function(item){
    if(item[option.id]==id){
      node=item;
      return false;
    }
  });
  return node;
}

export default {
  foreachTree,formatTree,findById
}